package com.imagination.applet.infrastructure.logging;

import com.imagination.applet.infrastructure.utils.ObjectMapperUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Aspect
@Component
@Slf4j
public class LogAdvice {

    @Pointcut("@within(com.imagination.applet.infrastructure.logging.Log) || @annotation(com.imagination.applet.infrastructure.logging.Log)")
    public void logPointCut() {

    }

    @Around(value = "logPointCut()")
    public Object logging(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        String methodName = getMethodName(proceedingJoinPoint);
        Object[] param = proceedingJoinPoint.getArgs();

        log.info("[ {} ], arguments : {}", methodName, ObjectMapperUtils.write(param));

        // 环绕通知最重要：定义整个目标方法都要执行
        Object object = proceedingJoinPoint.proceed();

        log.info("[ {} ], return : {}", methodName, ObjectMapperUtils.write(object));

        return object;
    }

    private String getMethodName(ProceedingJoinPoint proceedingJoinPoint) {
        String className = proceedingJoinPoint.getTarget().getClass().getName();
        String methodName = proceedingJoinPoint.getSignature().getName();
        return className + "." + methodName;
    }
}
